home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / pvm34b3.zip / pvm34b3 / pvm3 / xep / mmain.c < prev    next >
C/C++ Source or Header  |  1997-07-22  |  6KB  |  238 lines

  1.  
  2. static char rcsid[] =
  3.     "$Id: mmain.c,v 1.2 1997/07/09 13:56:55 pvmsrc Exp $";
  4.  
  5. /*
  6.  *         PVM version 3.4:  Parallel Virtual Machine System
  7.  *               University of Tennessee, Knoxville TN.
  8.  *           Oak Ridge National Laboratory, Oak Ridge TN.
  9.  *                   Emory University, Atlanta GA.
  10.  *      Authors:  J. J. Dongarra, G. E. Fagg, M. Fischer
  11.  *          G. A. Geist, J. A. Kohl, R. J. Manchek, P. Mucci,
  12.  *         P. M. Papadopoulos, S. L. Scott, and V. S. Sunderam
  13.  *                   (C) 1997 All Rights Reserved
  14.  *
  15.  *                              NOTICE
  16.  *
  17.  * Permission to use, copy, modify, and distribute this software and
  18.  * its documentation for any purpose and without fee is hereby granted
  19.  * provided that the above copyright notice appear in all copies and
  20.  * that both the copyright notice and this permission notice appear in
  21.  * supporting documentation.
  22.  *
  23.  * Neither the Institutions (Emory University, Oak Ridge National
  24.  * Laboratory, and University of Tennessee) nor the Authors make any
  25.  * representations about the suitability of this software for any
  26.  * purpose.  This software is provided ``as is'' without express or
  27.  * implied warranty.
  28.  *
  29.  * PVM version 3 was funded in part by the U.S. Department of Energy,
  30.  * the National Science Foundation and the State of Tennessee.
  31.  */
  32.  
  33. /*
  34.  *    main.c
  35.  *
  36.  *    Mandelbrot calculator.
  37.  *    Uses tile processes to calculate strips from the requested
  38.  *    region, cats the strips together.
  39.  *
  40.  *    Usage:
  41.  *        main width height x1 y1 x2 y2 filename
  42.  *        ( main 256 256 -2.0 -2.0 2.0 2.0 whole_mandelbrot )
  43.  *
  44.  *    3 Jun 1991  Robert Manchek  manchek@CS.UTK.EDU.
  45.  *    22 Sep 91 - took out ncpus command arg because we can find out from pvm
  46.  *    02 Sep 92  - ported to v3
  47.  */
  48.  
  49. #ifdef HASSTDLIB
  50. #include <stdlib.h>
  51. #endif
  52. #include <sys/types.h>
  53. #include <fcntl.h>
  54. #include <stdio.h>
  55. #include <math.h>
  56. #include "pvm3.h"
  57. #include "../src/bfunc.h"
  58.  
  59. char *mandelbrot();
  60.  
  61. int nprocessors = 1;        /* number of processors to use */
  62. int *prtids = 0;            /* processor task ids */
  63.  
  64. main(argc, argv)
  65.     int argc;
  66.     char **argv;
  67. {
  68.     int mytid;                /* my task id */
  69.     int wd = 16, ht = 16;    /* size of image to calculate */
  70.     double x1, y1, x2, y2;    /* image corner coordinates */
  71.     char *pix;                /* image data */
  72.     int d;                    /* output file */
  73.     int i;                    /* gp */
  74.     char *dfn;                /* file to write to */
  75.  
  76.     if (argc != 8) goto usage;
  77.     wd = atoi(argv[1]);
  78.     ht = atoi(argv[2]);
  79.     x1 = atof(argv[3]);
  80.     y1 = atof(argv[4]);
  81.     x2 = atof(argv[5]);
  82.     y2 = atof(argv[6]);
  83.     dfn = argv[7];
  84.     if (wd < 1 || wd > 2048 || ht < 1 || ht > 2048) {
  85.         fputs("width and heigh must be between 1 and 2048\n", stderr);
  86.         goto usage;
  87.     }
  88.  
  89.     /* enroll in pvm */
  90.     
  91.     if ((mytid = pvm_mytid()) < 0) {
  92.         exit(1);
  93.     }
  94. /*
  95.     printf("i'm t%x\n", mytid);
  96. */
  97.  
  98.     pvm_config(&nprocessors, (int*)0, (struct pvmhostinfo**)0);
  99.     if (nprocessors > wd)
  100.         nprocessors = wd;
  101.     fprintf(stderr, "using %d tile servers in calculation\n", nprocessors);
  102.  
  103.     /* create n instances of tile */
  104.  
  105.     prtids = (int*)malloc(nprocessors * sizeof(int));
  106. /*
  107.     if (pvm_spawn("mtile", (char**)0, 0, "", nprocessors, prtids) < 0) {
  108.         fputs("can't initiate calculators\n", stderr);
  109.         pvm_exit();
  110.         exit(1);
  111.     }
  112. */
  113.     for (i = 0; i < nprocessors; i++) {
  114.         if (pvm_spawn("mtile", (char**)0, 0, "", 1, &prtids[i]) < 0) {
  115.             fputs("can't initiate calculator\n", stderr);
  116.             pvm_exit();
  117.             exit(1);
  118.         }
  119. /*
  120.         printf("task t%x\n", prtids[i]);
  121. */
  122.     }
  123.  
  124.     pix = mandelbrot(x1, y1, x2, y2, wd, ht);
  125.  
  126.     fputs("writing\n", stderr);
  127.     if ((d = open(dfn, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1) {
  128.         perror(dfn);
  129.  
  130.     } else {
  131.         (void)write(d, pix, wd * ht);
  132.         (void)close(d);
  133.         fprintf(stderr, "%s: written\n", dfn);
  134.     }
  135.  
  136.     /* kill processors we created */
  137.  
  138.     for (i = 0; i < nprocessors; i++)
  139.         pvm_kill(prtids[i]);
  140.  
  141.     /* un-enroll from pvm */
  142.  
  143.     pvm_exit();
  144.     exit(0);
  145.  
  146. usage:
  147.     fputs("usage: mmain width height x1 y1 x2 y2 filename\n",
  148.         stderr);
  149.     exit(1);
  150. }
  151.  
  152. char*
  153. mandelbrot(x1, y1, x2, y2, wd, ht)
  154.     double x1, y1, x2, y2;
  155.     int wd, ht;
  156. {
  157.     char *pix = 0;        /* calculated image */
  158.     char *tile = 0;        /* data from a single strip */
  159.     int *tpos;            /* tile positions */
  160.     int maxwd = 0;        /* maximum width of strip */
  161.     int slavetid;        /* processor id responding */
  162.     int twd;            /* width of a tile */
  163.     double xyxy[4];        /* gp */
  164.     int wdht[2];        /* gp */
  165.     int i, j;            /* gp */
  166.     int y;                /* gp */
  167.     char *ba1, *ba2;    /* gp */
  168.  
  169.     pix = (char*)malloc(wd * ht);
  170.  
  171.     /* divide up area into strips and assign them to processors */
  172.  
  173.     tpos = (int*)malloc((nprocessors + 1) * sizeof(int));
  174.     x2 -= x1;
  175.     xyxy[0] = x1;
  176.     xyxy[1] = y1;
  177.     xyxy[3] = y2;
  178.     wdht[1] = ht;
  179.     tpos[0] = 0;
  180.     fputs("sending work to processors\n", stderr);
  181.     for (i = 0; i < nprocessors; i++) {
  182.         pvm_initsend(PvmDataDefault);
  183.         tpos[i + 1] = ((i + 1) * wd) / nprocessors;
  184.         wdht[0] = tpos[i + 1] - tpos[i];
  185.         if (wdht[0] > maxwd)
  186.             maxwd = wdht[0];
  187.         xyxy[2] = (tpos[i + 1] * x2) / wd + x1;
  188.         pvm_pkdouble(xyxy, 4, 1);
  189.         pvm_pkint(wdht, 2, 1);
  190.         if (pvm_send(prtids[i], 1)) {
  191.             fprintf(stderr, "error sending to <%x>\n", prtids[i]);
  192.             pvm_exit();
  193.             exit(1);
  194.         }
  195.         xyxy[0] = xyxy[2];
  196.     }
  197.  
  198.     /* collect results and patch together */
  199.  
  200.     tile = (char*)malloc(maxwd * ht);
  201.     fputs("processors responding:", stderr); fflush(stderr);
  202.     for (i = 0; i < nprocessors; i++) {
  203.         if (pvm_recv(-1, 2) < 1) {
  204.             fprintf(stderr, "error receiving message type 2\n");
  205.             pvm_exit();
  206.             exit(1);
  207.         }
  208.         pvm_bufinfo(pvm_getrbuf(), &j, (int*)0, &slavetid);
  209. /*
  210.     fprintf(stderr, "len %d\n", j);
  211. */
  212.         for (j = 0; j < nprocessors; j++)
  213.             if (prtids[j] == slavetid) break;
  214.         if (j < nprocessors) {
  215.             fprintf(stderr, " %d", j);
  216.             fflush(stderr);
  217.             twd = tpos[j + 1] - tpos[j];
  218.             pvm_upkbyte(tile, twd * ht, 1);
  219.             ba1 = tile;
  220.             ba2 = pix + tpos[j];
  221.             for (y = ht; y-- > 0; ) {
  222.                 BCOPY(ba1, ba2, twd);
  223.                 ba1 += twd;
  224.                 ba2 += wd;
  225.             }
  226.  
  227.         } else {
  228.             fprintf(stderr, "got response from unknown processor %x?\n",
  229.                 slavetid);
  230.         }
  231.     }
  232.     fputs("\n", stderr);
  233.     free(tpos);
  234.     free(tile);
  235.     return pix;
  236. }
  237.  
  238.